home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
sat
/
msat09.tgz
/
XWEBER.C
< prev
Wrap
Text File
|
1994-09-17
|
13KB
|
651 lines
/*
* Copyright 1992, 1993, 1994 John Melton (G0ORX/N6LYT)
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
xweber.c
Weber Photo Image Capture
John Melton
G0ORX, N6LYT
4 Charlwoods Close
Copthorne
West Sussex
RH10 3QZ
England
INTERNET: g0orx@amsat.org
n6lyt@amsat.org
john@images.demon.co.uk
J.D.Melton@slh0613.icl.wins.co.uk
History:
-------
0.1 Initial version.
0.2 Changed code to update line in file.
0.3 Experimental SPECTRUM capture.
0.4 Converted to Xaw.
*/
/*
#define DEBUG
#define USEDATA
#define SAVEDATA
*/
#define VERSION_STRING "(version 0.4 by g0orx/n6lyt/g4klx)"
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Text.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/ax25.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>
#include "weber.h"
Display *dpy;
XtAppContext app_context;
typedef struct
{
XFontStruct *button_font, *text_font;
}
Resources;
Resources resources;
Widget toplevel, compwindow, quitbutton, datawindow;
char writebuf[100];
XtResource resource_list[] =
{
{"buttonFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
XtOffsetOf(Resources, button_font), XtRString, XtDefaultFont},
{"textFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
XtOffsetOf(Resources, text_font), XtRString, XtDefaultFont}
};
Arg shell_args[] =
{
{XtNtitle, (XtArgVal)NULL}
};
Arg form_args[] =
{
{XtNdefaultDistance, (XtArgVal)0}
};
Arg button_args[] =
{
{XtNcallback, (XtArgVal)NULL},
{XtNlabel, (XtArgVal)NULL},
{XtNfromHoriz, (XtArgVal)NULL},
{XtNfont, (XtArgVal)NULL},
{XtNresize, (XtArgVal)False},
{XtNvertDistance, (XtArgVal)6},
{XtNhorizDistance, (XtArgVal)8},
{XtNtop, XtChainTop},
{XtNbottom, XtChainTop},
{XtNleft, XtChainLeft},
{XtNright, XtChainLeft}
};
Arg window_args[] =
{
{XtNfromVert, (XtArgVal)NULL},
{XtNbackground, (XtArgVal)NULL},
{XtNfont, (XtArgVal)NULL},
{XtNcursor, (XtArgVal)NULL},
{XtNwidth, (XtArgVal)600},
{XtNheight, (XtArgVal)150},
{XtNvertDistance, (XtArgVal)6},
{XtNhorizDistance, (XtArgVal)0},
{XtNtop, XtChainTop},
{XtNbottom, XtChainBottom},
{XtNleft, XtChainLeft},
{XtNright, XtChainRight},
{XtNeditType, XawtextEdit},
{XtNtype, XawAsciiString},
{XtNwrap, XawtextWrapLine},
{XtNdisplayNonprinting, False},
{XtNdisplayCaret, False},
{XtNsensitive, False}
};
char satelliteId[16];
int s_raw;
XtInputId infd;
#define MAXBUFFER 512
unsigned char buf[MAXBUFFER];
int bufSize;
int bytes;
unsigned char expanded[MAXBUFFER*2];
int nExpanded;
int imageSeen = 0;
char photoName[256];
unsigned char image[160000];
int spectrumSeen = 0;
char spectrumName[256];
unsigned char spectrum[SPECTRUMLENGTH];
char text[256];
int frames = 0;
int bytes = 0;
int crcErrors = 0;
int x, y;
int offset;
unsigned char *imagePtr;
int fileBytes = 0;
void writetext(char *text)
{
XawTextPosition pos;
XawTextBlock tt;
return;
tt.firstPos = 0;
tt.ptr = text;
tt.length = strlen(text);
tt.format = FMT8BIT;
pos = XawTextGetInsertionPoint(datawindow);
XawTextReplace(datawindow, pos, pos, &tt);
pos += tt.length;
XawTextSetInsertionPoint(datawindow, pos);
}
/*
* Convert a call from the shifted ascii form used in an
* AX.25 packet.
*/
int ConvertCall(char *c, char *call)
{
char *ep = c + 6;
int ct =0;
while (ct < 6)
{
if (((*c >> 1) & 127) == ' ') break;
*call = (*c >> 1) & 127;
call++;
ct++;
c++;
}
if ((*ep & 0x1E) != 0)
{
*call = '-';
call++;
call += sprintf(call, "%d", (int)(((*ep) >> 1) & 0x0F));
}
*call = '\0';
if (*ep & 1) return 0;
return 1;
}
void SetPixel(unsigned char pixel)
{
*imagePtr = pixel;
imagePtr += 3;
}
/*
* process photodata
*/
void PhotoData(char *photoId, unsigned char *buffer, int length)
{
HEADER *p;
unsigned char *data;
unsigned char line[WIDTH];
int i,j,n;
int f;
strcpy(photoName, photoId);
p = (HEADER *)buffer;
if ((p->flags & 0x03) == 0x03)
{
int bytes;
/* ascii text info */
bytes = length-1;
if (bytes > 255) bytes = 255;
sprintf(writebuf, "%s: ascii text (%d)\n", photoId, bytes);
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s: ascii text (%d)\n", photoId, bytes);
fflush(stderr);
#endif
strncpy(text, buffer + 1, bytes);
sprintf(writebuf, "%s\n", buffer + 1);
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s\n", buffer + 1);
fflush(stderr);
#endif
/* update the text info in the front of the file */
if ((f = open(photoName, O_RDWR, 0660)) != -1)
{
write(f, text, 256);
}
else
{
f = creat(photoName, 0660);
write(f, text, 256);
}
close(f);
}
else
{
x = (p->flags << 8) | p->xLoc;
y = p->yLoc / 2;
offset = (y * WIDTH) + 256;
data = buffer + sizeof(HEADER);
imagePtr = line + x;
sprintf(writebuf, "%s: x=%d y=%d\n", photoId, x, y);
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s: x=%d y=%d flags=%d offset=%d ptr=%x\n", photoId, x, y, p->flags, offset, (int)imagePtr);
fflush(stderr);
#endif
if ((f = open(photoName, O_RDWR, 0660)) != -1)
{
lseek(f, offset, SEEK_SET);
if (read(f, line, WIDTH) <= 0)
for (i = 0; i < WIDTH; i++)
line[i] = 0;
}
else
{
for (i = 0; i < WIDTH; i++)
line[i] = 0;
f = creat(photoName, 0660);
}
for (i = 0; i < (length-sizeof(HEADER)); i++)
{
if (data[i])
{
*imagePtr = data[i];
imagePtr += 3;
}
else
{
i++;
n = data[i++];
for (j = 0; j < n; j++)
{
*imagePtr = data[i];
imagePtr += 3;
}
}
}
#ifdef DEBUG
fprintf(stderr, "updating image file\n");
fflush(stderr);
#endif
lseek(f, offset, SEEK_SET);
write(f, line, WIDTH);
close(f);
}
}
void SpectrumData(char *spectrumId, unsigned char *buffer, int length)
{
int f;
int start, end;
int i;
if (spectrumSeen == 0)
{
strcpy(spectrumName, spectrumId);
if ((f = open(spectrumName, O_RDWR, 0660)) != -1)
{
read(f, text, 256);
read(f, spectrum, SPECTRUMLENGTH);
close(f);
}
spectrumSeen = 1;
}
if (buffer[0] == 0x0D && buffer[1] == 0x0A)
{
int bytes;
/* ascii text info */
bytes = length;
if (bytes > 255) bytes = 255;
sprintf(writebuf, "%s: ascii text (%d)\n", spectrumId, bytes);
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s: ascii text (%d)\n", spectrumId, bytes);
#endif
strncpy(text, buffer, bytes);
sprintf(writebuf, "%s\n", buffer);
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s\n", buffer);
#endif
}
else
{
start = buffer[0] * 128;
end = buffer[1] * 128;
sprintf(writebuf, "%s: start=%d end=%d\n", spectrumId, start, end );
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s: start=%d end=%d\n", spectrumId, start, end);
#endif
for (i = 0; i < 128; i++)
spectrum[i] = buffer[i + 2];
}
#ifdef DEBUG
fprintf(stderr, "updating spectrum file\n");
#endif
/* update the image file */
/*
f = creat(spectrumName, 0660);
write(f, text, 256);
write(f, spectrum, SPECTRUMLENGTH);
close(f);
*/
#ifdef DEBUG
fprintf(stderr, "exiting\n");
#endif
}
/*
* decode a received frame.
*/
void ProcessFrame(void)
{
int n;
int via;
unsigned char protocol;
char toCall[10];
char fromCall[10];
char viaCall[10];
frames++;
bytes+=bufSize;
/* check that frame is a kiss data frame */
/* ignore control frames - should not happen */
n = 0;
if ((buf[n] & 0x0F) == 0)
{
n++;
/* decode the to/from address */
/* dont expect via address, but saves last if any */
via = ConvertCall(buf + n, toCall);
n+=7;
via = ConvertCall(buf + n, fromCall);
n+=7;
while (via)
{
via = ConvertCall(buf + n, viaCall);
n += 7;
}
/* check for a UI frame */
if ((buf[n] & 0xEF) == 0003)
{
n++;
protocol = buf[n++];
/* see if this is a photo frame */
if (strncmp(toCall, "PHOTO", 5) == 0)
{
PhotoData(toCall, buf + n, bufSize - n);
}
else if (strncmp(toCall, "SPECT", 5) == 0)
{
SpectrumData(toCall, buf + n, bufSize - n);
}
else if (strcmp(toCall, "PBLIST") == 0 ||
strcmp(toCall, "BBSTAT") == 0 ||
strcmp(toCall, "QST") == 0 ||
strcmp(toCall, "AMSAT") == 0 ||
strcmp(toCall, "LSTAT") == 0 ||
strcmp(toCall, "BSTAT") == 0 ||
strcmp(toCall, "HITVER") == 0 ||
strcmp(toCall, "TIME-1") == 0)
{
buf[bufSize] = '\0';
sprintf(writebuf, "%s\n", buf + n);
writetext(writebuf);
#ifdef DEBUG
fprintf(stderr, "%s\n", buf + n);
fflush(stderr);
#endif
}
}
}
}
/*
* callback function when a frame is received.
*/
void GetFrame(XtPointer closure, int *s, XtInputId *Id)
{
#ifdef USEDATA
if (ioctl(s_raw, FIONREAD, &bytes) == -1 || bytes == 0)
{
XtRemoveInput(infd);
return;
}
if ((bytes = read(s_raw, (char *)&bufSize, sizeof(bufSize))) > 0)
{
if ((bufSize = read(s_raw, buf, bufSize)) == -1)
{
perror("read 1");
return;
}
}
else
{
perror("read 2");
return;
}
#else
if ((bufSize = recv(s_raw, buf, MAXBUFFER, 0)) == -1)
{
perror("recv");
return;
}
#endif
#ifdef SAVEDATA
{
int f;
if ((f = open("DATA", O_RDWR | O_CREAT, 0666)) != -1)
{
lseek(f, 0L, SEEK_END);
write(f, (char *)&bufSize, sizeof(bufSize));
write(f, buf, bufSize);
close(f);
}
}
#endif
fileBytes += bufSize;
ProcessFrame();
}
/*
* the user wants to exit this program
*/
void QuitCb(Widget w, XtPointer client_data, XtPointer call_data)
{
int f;
/* print some stats */
fprintf(stderr, "\nReceived:\n" );
fprintf(stderr, " totalFrames=%d\n", frames);
fprintf(stderr, " totalBytes=%d\n", bytes);
fprintf(stderr, " crcErrors=%d\n", crcErrors);
fprintf(stderr, " fileBytes=%d\n", fileBytes);
/* close the sockets */
close(s_raw);
if (imageSeen == 1)
{
f = creat(photoName, 0660);
write(f, text, 256);
write(f, image, WIDTH*HEIGHT);
close(f);
}
/* get out */
XtDestroyApplicationContext(app_context);
exit(0);
}
int main(int argc, char **argv)
{
static XtCallbackRec callback[2];
char *s, title[80];
if ((s = getenv("SATELLITE")) == NULL)
{
printf("SATELLITE environment variable not set.\n");
return(1);
}
strcpy(satelliteId, s);
sprintf(title, "xweber:%s %s", satelliteId, VERSION_STRING);
toplevel = XtAppInitialize(&app_context, "Xpb", NULL, 0, &argc, argv,
NULL, shell_args, XtNumber(shell_args));
XtVaSetValues(toplevel, XtNtitle, title, NULL);
dpy = XtDisplay(toplevel);
XtGetApplicationResources(toplevel, &resources,
resource_list, XtNumber(resource_list),
NULL, ZERO);
compwindow = XtCreateManagedWidget("appForm", formWidgetClass,
toplevel, form_args, XtNumber(form_args));
callback[0].callback = QuitCb;
callback[0].closure = toplevel;
button_args[0].value = (XtArgVal)callback;
button_args[1].value = (XtArgVal)"Quit";
button_args[3].value = (XtArgVal)resources.button_font;
quitbutton = XtCreateManagedWidget("quitButton", commandWidgetClass,
compwindow, button_args, XtNumber(button_args));
window_args[0].value = (XtArgVal)quitbutton;
window_args[1].value = (XtArgVal)WhitePixel(dpy, DefaultScreen(dpy));
window_args[2].value = (XtArgVal)resources.text_font;
datawindow = XtCreateManagedWidget("monitorText", asciiTextWidgetClass,
compwindow, window_args, XtNumber(window_args));
#ifdef USEDATA
/* open up the data file */
if ((s_raw = open("DATA", O_RDONLY)) == -1)
{
perror("open");
return(1);
}
#else
/* open up the raw socket to receive all packets */
if ((s_raw = socket(AF_INET, SOCK_PACKET, htons(2))) == -1)
{
perror("socket");
return(1);
}
#endif
/* we want to be notified whenever a frame is received on the raw socket */
infd = XtAppAddInput(app_context, s_raw, (XtPointer)XtInputReadMask, GetFrame, NULL);
XtRealizeWidget(toplevel);
XtAppMainLoop(app_context);
return(0);
}